/*
 * monitor.cpp
 *
 *  Created on: 2017年6月15日
 *      Author: work
 */

#include <dm/os/io/monitor.hpp>

#include <unistd.h>
#include <cstdio>

namespace dm{
namespace os{
namespace io{

CMonitor::CMonitor( const unsigned int& size):m_size(0),m_count(0),m_fds(NULL){
	setSize(size);
}

CMonitor::~CMonitor(){
	setSize(0);
}

/**
 * 设置缓冲区大小
 * 同时将count设置为0
 * @param size
 */
void CMonitor::setSize( const unsigned int& size ){
	if( m_size!=size ){
		if( m_size>0 && m_fds!=NULL )
			delete [] m_fds;
		m_size = size;
		if( m_size>0 )
			m_fds = new struct pollfd[m_size];
		else
			m_fds = NULL;
	}
	m_count = 0;
}

void CMonitor::reset(){
	m_count = 0;
}

bool CMonitor::wait( const long timeout_ms ){
	for( unsigned int i=0;i<m_count;++i ){
		m_fds[i].events = POLLIN;
	}

	return poll(m_fds,m_count,timeout_ms);
}

int CMonitor::addIo( CIo& io ){
	return addIo(io.m_fd);
}

int CMonitor::addIo( int fd ){
	unsigned int i = 0;
	for(;i<m_count;++i ){
		if( m_fds[i].fd==fd )
			return i;
	}

	if( m_count>=m_size )
		return -1;	// 空间不够

	m_fds[i].fd = fd;
	++m_count;

	return i;
}

bool CMonitor::isReady( const unsigned int& index )const{
	if( index>=m_count )
		return false;
	return 0!=(m_fds[index].revents & (POLLIN|POLLERR));
}

bool CMonitor::isIoReady( const int& fd )const{
	int i = getIndex(fd);
	if( i<0 )
		return false;
	return isReady(i);
}

int CMonitor::getIndex( const int& fd )const{
	for( unsigned int i=0;i<m_count;++i )
		if( m_fds[i].fd==fd )
			return i;
	return -1;
}

}
}
}


